// 该页面为微博编辑页面，已归类到 weibo 目录
<script setup lang="ts">
  import { saveOrUpdate } from '@/api/weibo.ts'
  import { upload } from '@/api/file.ts'
  import { WeiboSaveOrUpdateParam, Weibo } from '@/types'
  import { Plus, Close } from '@element-plus/icons-vue'
  import type { UploadProps, UploadUserFile } from 'element-plus'
  import { ElMessage } from 'element-plus'
  import type { PropType } from 'vue'
  import { computed, onMounted, ref } from 'vue'

  // 定义组件的 props
  const { data, close, isEdit } = defineProps({
    data: {
      type: Object as PropType<Weibo>,
      required: false,
      default: () => ({}),
    },
    close: {
      type: Function as PropType<() => void>,
      required: true,
    },
    isEdit: {
      type: Boolean,
      required: false,
      default: false,
    },
  })

  // 定义上传文件的接口
  interface WeiboUploadUserFile extends UploadUserFile {
    id: string
    fileName: string
    url: string
  }

  // 定义响应式变量
  const content = ref('') // 微博内容
  const fileList = ref<WeiboUploadUserFile[]>([]) // 上传的文件列表
  const loading = ref(false) // 加载状态

  // 所有图片URL列表用于预览
  const imageUrlList = computed(() => {
    return fileList.value.map(file => file.url)
  })

  // 初始化数据
  const initData = () => {
    if (data) {
      content.value = data.content // 设置内容
      fileList.value =
        data.files?.map(file => ({
          name: file.fileName,
          fileName: file.fileName,
          url: file.url,
          id: file.id,
        })) || [] // 设置文件列表
    }
  }

  // 组件挂载后初始化数据
  onMounted(() => {
    initData()
  })

  // 图片压缩函数
  const compressImage = (file: File, quality: number = 0.8): Promise<File> => {
    return new Promise(resolve => {
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')!
      const img = new Image()

      img.onload = () => {
        // 计算压缩后的尺寸
        let { width, height } = img
        const maxSize = 1920 // 最大尺寸

        if (width > height && width > maxSize) {
          height = (height * maxSize) / width
          width = maxSize
        } else if (height > maxSize) {
          width = (width * maxSize) / height
          height = maxSize
        } else {
          width = maxSize
        }

        canvas.width = width
        canvas.height = height

        // 绘制压缩后的图片
        ctx.drawImage(img, 0, 0, width, height)

        // 转换为Blob并创建新的File对象
        canvas.toBlob(
          blob => {
            if (blob) {
              const compressedFile = new File([blob], file.name, {
                type: file.type,
                lastModified: Date.now(),
              })
              resolve(compressedFile)
            } else {
              resolve(file)
            }
          },
          file.type,
          quality
        )
      }

      img.src = URL.createObjectURL(file)
    })
  }

  // 图片上传前的处理
  const beforeUpload: UploadProps['beforeUpload'] = async file => {
    const isImage = file.type.startsWith('image/') // 检查文件类型
    if (!isImage) {
      ElMessage.error('只能上传图片文件！') // 错误提示
      return false
    }

    const fileSizeInMB = file.size / 1024 / 1024

    // 如果文件大于1MB，进行压缩
    if (fileSizeInMB > 1) {
      ElMessage.info('检测到大文件，正在压缩处理...')
      try {
        const compressedFile = await compressImage(file, 0.8)
        const compressedSizeInMB = compressedFile.size / 1024 / 1024

        console.log(`原始文件大小: ${fileSizeInMB.toFixed(2)}MB`)
        console.log(`压缩后文件大小: ${compressedSizeInMB.toFixed(2)}MB`)
        // 如果压缩后小于2MB，直接返回压缩后的文件
        if (compressedSizeInMB < 2) {
          ElMessage.success('文件压缩完成')
          return compressedFile
        }
        // 如果压缩后仍然大于2MB，降低质量再次压缩
        const secondCompressedFile = await compressImage(file, 0.5)
        const finalSizeInMB = secondCompressedFile.size / 1024 / 1024

        if (finalSizeInMB > 2) {
          ElMessage.error('图片文件过大，压缩后仍超过2MB限制！')
          return false
        }

        ElMessage.success('文件压缩完成')
        return secondCompressedFile
      } catch (error) {
        console.error('图片压缩失败:', error)
        ElMessage.error('图片压缩失败，请重试')
        return false
      }
    }

    // 小于1MB的文件直接通过，但仍需检查是否超过2MB限制
    if (fileSizeInMB > 2) {
      ElMessage.error('图片大小不能超过 2MB!')
      return false
    }

    return true
  }

  // 自定义上传方法 - 使用统一的文件上传API
  const customUpload: UploadProps['httpRequest'] = async options => {
    // 如果beforeUpload返回的是压缩后的文件，使用压缩后的文件
    const fileToUpload = options.file

    console.log('上传文件:', fileToUpload)

    try {
      // 使用统一的文件上传API，type参数设为2表示微博图片
      const response = await upload([fileToUpload], 2)
      console.log('上传响应:', response)
      return response
    } catch (error) {
      console.error('上传出错:', error)
      if (options.onError) {
        options.onError({
          status: 500,
          method: 'post',
          url: '/file/upload',
          name: 'UploadError',
          message: (error as Error).message || '上传失败',
        })
      }
    }
  }

  // 图片上传成功的处理
  const handleSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
    const fileData = response?.[0] // 获取第一个文件的数据
    if (fileData) {
      // 更新上传文件的属性
      uploadFile.url = fileData.url
      ;(uploadFile as WeiboUploadUserFile).fileName = fileData.fileName
      ;(uploadFile as WeiboUploadUserFile).id = fileData.id

      // 将上传的文件添加到fileList中以便显示
      const newFile: WeiboUploadUserFile = {
        ...(uploadFile as WeiboUploadUserFile),
        name: fileData.fileName,
        id: fileData.id,
        fileName: fileData.fileName,
        url: fileData.url,
      }

      // 添加到文件列表
      fileList.value.push(newFile)

      // 调试日志
      console.log('文件上传成功:', fileData)
      console.log('当前文件列表:', fileList.value)
    }
  }

  // 图片上传失败的处理
  const handleError: UploadProps['onError'] = () => {
    ElMessage.error('上传失败') // 错误提示
  }

  // 处理自定义删除事件
  const handleCustomRemove = (file: WeiboUploadUserFile) => {
    const index = fileList.value.indexOf(file)
    if (index !== -1) {
      fileList.value.splice(index, 1)
    }
  }

  // 保存微博
  const handleSave = async () => {
    if (!content.value.trim()) {
      ElMessage.warning('请输入微博内容') // 提示用户输入内容
      return
    }

    loading.value = true // 开始加载
    try {
      const param: WeiboSaveOrUpdateParam = {
        id: data?.id,
        content: content.value,
        files: fileList.value.map(file => file.id), // 获取文件 ID
      }
      await saveOrUpdate(param) // 保存或更新微博
      ElMessage.success('保存成功') // 成功提示
      close() // 关闭编辑框
    } catch (error) {
      ElMessage.error('保存失败') // 错误提示
      console.error('保存微博失败:', error)
    } finally {
      loading.value = false // 结束加载
    }
  }
</script>

<template>
  <div class="weibo-edit">
    <el-form>
      <el-form-item>
        <el-input
          v-model="content"
          type="textarea"
          :rows="5"
          placeholder="分享新鲜事..."
          maxlength="500"
          show-word-limit
          :disabled="!isEdit"
          class="content-input"
        />
      </el-form-item>

      <div class="image-upload-container">
        <div class="image-grid">
          <!-- 已上传的图片 -->
          <div v-for="(file, index) in fileList" :key="file.uid || index" class="image-item">
            <el-image
              :src="file.url"
              fit="cover"
              class="uploaded-image"
              :preview-src-list="imageUrlList"
              :initial-index="index"
              :hide-on-click-modal="true"
            />
            <div v-if="isEdit" class="remove-icon" @click="handleCustomRemove(file)">
              <el-icon>
                <Close />
              </el-icon>
            </div>
          </div>

          <!-- 上传按钮 -->
          <div v-if="isEdit && fileList.length < 9" class="upload-button-wrapper">
            <el-upload
              :file-list="[]"
              :http-request="customUpload"
              :on-error="handleError"
              :on-success="handleSuccess"
              :before-upload="beforeUpload"
              multiple
              :show-file-list="false"
              :disabled="!isEdit"
              :auto-upload="true"
              class="custom-upload"
            >
              <div class="upload-button">
                <el-icon>
                  <Plus />
                </el-icon>
              </div>
            </el-upload>
          </div>
        </div>
      </div>

      <el-form-item class="action-buttons">
        <el-button type="primary" :loading="loading" :disabled="!isEdit" @click="handleSave">
          发布
        </el-button>
        <el-button @click="close">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<style scoped>
  .weibo-edit {
    padding: 20px;
    background-color: #fff;
    border-radius: 8px;
  }

  .content-input {
    margin-bottom: 10px;
  }

  .content-input :deep(.el-textarea__inner) {
    padding: 16px;
    font-size: 15px;
    resize: none;
    background-color: #f5f5f5;
    border-radius: 8px;
  }

  .image-upload-container {
    margin-bottom: 20px;
    width: 100%;
  }

  .image-grid {
    display: grid;
    grid-template-columns: repeat(3, 100px);
    gap: 8px;
    margin-bottom: 16px;
  }

  .image-item {
    position: relative;
    width: 100px;
    height: 100px;
    border-radius: 4px;
    overflow: hidden;
  }

  .uploaded-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .remove-icon {
    position: absolute;
    top: 3px;
    right: 3px;
    background-color: rgba(0, 0, 0, 0.6);
    color: #fff;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    z-index: 1;
    font-size: 12px;
    transition: all 0.2s;
  }

  .remove-icon:hover {
    background-color: rgba(0, 0, 0, 0.8);
    transform: scale(1.1);
  }

  .upload-button-wrapper {
    position: relative;
    width: 100px;
    height: 100px;
    cursor: pointer;
  }

  .custom-upload {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }

  .upload-button {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #f5f5f5;
    border-radius: 4px;
    border: 1px dashed #d9d9d9;
  }

  .action-buttons {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
  }
</style>
